package utils.http;

import cn.hutool.core.util.StrUtil;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpStatus;
import org.apache.http.client.CookieStore;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import utils.SmallTool;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author claud
 * 2018年8月15日18:25:28
 * 抽取的公共的httpclient
 */


public class HttpClientUtil {


    /**
     * 通用的获取html的get方法
     */
    public static String get(HttpClientConfig config) {
        SmallTool.printMess("当前的地址:" + config.getUrl());
        String html = null;

        CloseableHttpClient httpClient = HttpClients.custom().setDefaultCookieStore(config.getCookieStore()).setDefaultCredentialsProvider(config.getCredsProvider()).build();

        long time1 = System.currentTimeMillis();
        CloseableHttpResponse response;
        try {
            HttpGet httpget = new HttpGet(config.getUrl());
            httpget.setConfig(config.getRequestConfig());

            if (StrUtil.isNotEmpty(config.getConnection())) {
                httpget.addHeader(HttpHeaders.CONNECTION, config.getConnection());
            }

            if (StrUtil.isNotEmpty(config.getAcceptEncoding())) {
                httpget.addHeader(HttpHeaders.ACCEPT_ENCODING, config.getAcceptEncoding());
            }

            if (StrUtil.isNotEmpty(config.getAcceptLanguage())) {
                httpget.addHeader(HttpHeaders.ACCEPT_LANGUAGE, config.getAcceptLanguage());
            }

            if (StrUtil.isNotEmpty(config.getAccept())) {
                httpget.addHeader(HttpHeaders.ACCEPT, config.getAccept());
            }

            if (StrUtil.isNotEmpty(config.getReferer())) {
                httpget.addHeader(HttpHeaders.REFERER, config.getReferer());
            }

            if (StrUtil.isNotEmpty(config.getUserAgent())) {
                httpget.addHeader(HttpHeaders.USER_AGENT, config.getUserAgent());
            }

            if (StrUtil.isNotEmpty(config.getCacheContro())) {
                httpget.addHeader(HttpHeaders.CACHE_CONTROL, config.getCacheContro());
            }

            if (StrUtil.isNotEmpty(config.getCookie())) {
                httpget.addHeader("Cookie", config.getCookie());
            }

            /**
             * 添加相关的header
             */

            if (config.getHeaderMap() != null) {
                for (Map.Entry<String, String> entry : config.getHeaderMap().entrySet()) {
                    httpget.addHeader(entry.getKey(), entry.getValue());
                }
            }

            response = httpClient.execute(httpget);
            int resStatu = response.getStatusLine().getStatusCode();
            SmallTool.printMess("httpclient耗时" + (System.currentTimeMillis() - time1) + "--状态码" + resStatu);
            SmallTool.printMess(resStatu + "");
            if (resStatu == HttpStatus.SC_OK) {
                Header contentTypeHeader = response.getFirstHeader("Content-Type");
                SmallTool.printMess("header类型:" + contentTypeHeader);
                if (contentTypeHeader != null) {
                    String value = contentTypeHeader.getValue();
                    if (value.contains("application/pdf") || value.contains("application/octet-stream")) {
                        html = convertToPdf(response, config);
                        SmallTool.printMess("下载Pdf耗时：" + (System.currentTimeMillis() - time1));
                        return html;
                    }
                    if (value.contains("image/jpeg") || value.contains("image/png") || value.contains("image/gif")) {
                        html = HttpClientUtil.convertToImg(response, config.getSavePath());
                        SmallTool.printMess("下载图片耗时：" + (System.currentTimeMillis() - time1));
                        return html;
                    }
                }
                html = HttpClientUtil.parsingHtml(response);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            httpClient.getConnectionManager().shutdown();
        }

        SmallTool.printMess("请求耗时：" + (System.currentTimeMillis() - time1));
        return html;
    }

    /**
     * 通用的获取html的post方法
     */
    public static String post(HttpClientConfig config) {
        SmallTool.printMess("httpclient里面的地址" + config.getUrl());
        String html = "";
        CloseableHttpClient httpClient = HttpClients.custom().setDefaultCookieStore(config.getCookieStore()).setDefaultCredentialsProvider(config.getCredsProvider()).build();
        HttpPost httppost = null;
        long time1 = System.currentTimeMillis();
        CloseableHttpResponse responce;
        try {
            httppost = new HttpPost(config.getUrl());
            if (config.getNvpsList().size() > 0) {
                httppost.setEntity(new UrlEncodedFormEntity(config.getNvpsList(), "utf8"));
            }
            if (StrUtil.isNotEmpty(config.getPostDate())) {
                httppost.setEntity(new StringEntity(config.getPostDate(), "utf-8"));
            }
            httppost.setConfig(config.getRequestConfig());
            if (StrUtil.isNotEmpty(config.getConnection())) {
                httppost.addHeader(HttpHeaders.CONNECTION, config.getConnection());
            }

            if (StrUtil.isNotEmpty(config.getAcceptEncoding())) {
                httppost.addHeader(HttpHeaders.ACCEPT_ENCODING, config.getAcceptEncoding());
            }

            if (StrUtil.isNotEmpty(config.getAcceptLanguage())) {
                httppost.addHeader(HttpHeaders.ACCEPT_LANGUAGE, config.getAcceptLanguage());
            }

            if (StrUtil.isNotEmpty(config.getAccept())) {
                httppost.addHeader(HttpHeaders.ACCEPT, config.getAccept());
            }

            if (StrUtil.isNotEmpty(config.getReferer())) {
                httppost.addHeader(HttpHeaders.REFERER, config.getReferer());
            }

            if (StrUtil.isNotEmpty(config.getUserAgent())) {
                httppost.addHeader(HttpHeaders.USER_AGENT, config.getUserAgent());
            }

            if (StrUtil.isNotEmpty(config.getCacheContro())) {
                httppost.addHeader(HttpHeaders.CACHE_CONTROL, config.getCacheContro());
            }

            if (StrUtil.isNotEmpty(config.getCookie())) {
                httppost.addHeader("Cookie", config.getCookie());
            }

            if (StrUtil.isNotEmpty(config.getContentType())) {
                httppost.setHeader(HttpHeaders.CONTENT_TYPE, config.getContentType());

            }

            if (config.getHeaderMap() != null) {
                for (Map.Entry<String, String> entry : config.getHeaderMap().entrySet()) {
                    httppost.addHeader(entry.getKey(), entry.getValue());
                }
            }

            responce = httpClient.execute(httppost);
            int resStatu = responce.getStatusLine().getStatusCode();
            SmallTool.printMess("httpclient耗时" + (System.currentTimeMillis() - time1) + "状态码" + resStatu);
            if (resStatu == HttpStatus.SC_OK) {
                html = HttpClientUtil.parsingHtml(responce);
            }
        } catch (Exception e) {
            e.printStackTrace();
            SmallTool.printMess("查看异常的字符串" + e.toString());
            if (e.toString().contains("java.net.UnknownHostException")) {

            }
            if (e.toString().contains("connect time out")) {
            }
        } finally {
            httpClient.getConnectionManager().shutdown();
        }
        SmallTool.printMess("请求耗时：" + (System.currentTimeMillis() - time1));
        return html;
    }


    public static byte[] down(HttpClientConfig config) {
        CloseableHttpClient httpClient = HttpClients.custom().setDefaultCookieStore(config.getCookieStore()).setDefaultCredentialsProvider(config.getCredsProvider()).build();

        HttpGet httpget = null;
        long time1 = System.currentTimeMillis();
        CloseableHttpResponse response;
        try {
            httpget = new HttpGet(config.getUrl());
            httpget.setConfig(config.getRequestConfig());

            if (StrUtil.isNotEmpty(config.getConnection())) {
                httpget.addHeader(HttpHeaders.CONNECTION, config.getConnection());
            }

            if (StrUtil.isNotEmpty(config.getAcceptEncoding())) {
                httpget.addHeader(HttpHeaders.ACCEPT_ENCODING, config.getAcceptEncoding());
            }

            if (StrUtil.isNotEmpty(config.getAcceptLanguage())) {
                httpget.addHeader(HttpHeaders.ACCEPT_LANGUAGE, config.getAcceptLanguage());
            }

            if (StrUtil.isNotEmpty(config.getAccept())) {
                httpget.addHeader(HttpHeaders.ACCEPT, config.getAccept());
            }

            if (StrUtil.isNotEmpty(config.getReferer())) {
                httpget.addHeader(HttpHeaders.REFERER, config.getReferer());
            }

            if (StrUtil.isNotEmpty(config.getUserAgent())) {
                httpget.addHeader(HttpHeaders.USER_AGENT, config.getUserAgent());
            }

            if (StrUtil.isNotEmpty(config.getCacheContro())) {
                httpget.addHeader(HttpHeaders.CACHE_CONTROL, config.getCacheContro());
            }

            if (StrUtil.isNotEmpty(config.getCookie())) {
                httpget.addHeader("Cookie", config.getCookie());
            }

            /**
             * 添加相关的header
             */

            if (config.getHeaderMap() != null) {
                for (Map.Entry<String, String> entry : config.getHeaderMap().entrySet()) {
                    httpget.addHeader(entry.getKey(), entry.getValue());
                }
            }

            response = httpClient.execute(httpget);

            int resStatu = response.getStatusLine().getStatusCode();
            SmallTool.printMess("httpclient耗时" + (System.currentTimeMillis() - time1) + "--状态码" + resStatu);

            if (resStatu == HttpStatus.SC_OK) {
                HttpEntity entity = response.getEntity();
                return EntityUtils.toByteArray(entity);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            httpClient.getConnectionManager().shutdown();
        }
        return null;
    }


    /**
     * 打印cookie查看问题的方法
     */
    public static void printCookie(CookieStore bcs) {
        List<Cookie> list = bcs.getCookies();
        for (Cookie c : list) {
            System.out.println("cookie信息:" + c.toString());
        }
    }


    /**
     * 将各个httpclient获取的HttpResponse转化为相应的pdf
     */
    public static String convertToPdf(CloseableHttpResponse responce, HttpClientConfig config) {
        String pdfPath = "";
        HttpEntity entity = responce.getEntity();
        if (entity != null) {
            try {
                byte[] buffer = EntityUtils.toByteArray(entity);
                String fileName = config.getFileName();
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                createFile(config.getSavePath() + "/", config.getFileName(), buffer);
                pdfPath = config.getSavePath() + "/" + fileName;
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return pdfPath;
    }

    /**
     * 将各个httpclient获取的HttpResponse转化为相应的pdf
     */
    public static String convertToImg(CloseableHttpResponse response, String path) {
        String absPath = "";
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            try {
                byte[] buffer = EntityUtils.toByteArray(entity);
                String fileName = System.currentTimeMillis() + ".jpeg";
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                String time = format.format(new Date());
                createFile(path + "/" + time + "/", fileName, buffer);
                absPath = path + "/" + time + "/" + fileName;
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
        return absPath;
    }


    /**
     * 转化各个httpclient返回的html
     */
    public static String parsingHtml(CloseableHttpResponse responce) throws Exception {
        String html = null;
        HttpEntity entity = responce.getEntity();
        if (entity != null) {
            html = EntityUtils.toString(entity, "UTF-8");
            html = html.replace("&nbsp;", " ");
        }
        return html;
    }

    /**
     * 根据各个资源的路径生成对应的pdf
     */
    private static void createFile(String filePath, String fileName, byte[] content)
            throws IOException {
        File folder = new File(filePath);
        if (!folder.exists() && !folder.isDirectory()) {
            System.out.println("文件夹路径不存在，创建路径:" + filePath);
            folder.mkdirs();
        }
        FileOutputStream fos = new FileOutputStream(filePath + "/" + fileName);
        fos.write(content);
        fos.close();
    }

}
